package org.dtrd.modules.device.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.utils.IpUtils;
import org.apache.commons.lang3.StringUtils;
import org.dtrd.modules.device.config.DeviceConstant;
import org.dtrd.modules.device.config.DeviceConstant.DeviceBrand;
import org.dtrd.modules.device.config.DeviceConstant.DeviceCategory;
import org.dtrd.modules.device.entity.bean.bioland.SrcDataValue;
import org.dtrd.modules.device.entity.po.DtrdEntRdBioland;
import org.dtrd.modules.device.entity.po.DtrdEntRdBiolandPushContent;
import org.dtrd.modules.device.entity.po.DtrdEntRdDevice;
import org.dtrd.modules.device.mapper.DtrdEntRdBiolandPushContentMapper;
import org.dtrd.modules.device.service.IDtrdEntRdBiolandPushContentService;
import org.dtrd.modules.device.service.IDtrdEntRdBiolandService;
import org.dtrd.modules.device.service.IDtrdEntRdDeviceService;
import org.dtrd.modules.device.util.HdwDataCheckUtils;
import org.dtrd.modules.record.service.IBloodPressureRecordService;
import org.dtrd.modules.record.service.ISugarRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Calendar;

/**
 * @author 萧
 * @date 2021-09-01 00:02:01
 **/
@Service
@DS("multi-datasource1")
@Slf4j
public class DtrdEntRdBiolandPushContentServiceImpl extends ServiceImpl<DtrdEntRdBiolandPushContentMapper, DtrdEntRdBiolandPushContent> implements IDtrdEntRdBiolandPushContentService {

    @Autowired
    private ISugarRecordService sugarRecordService;

    @Autowired
    private IBloodPressureRecordService bloodPressureRecordService;

    @Autowired
    private IDtrdEntRdBiolandService biolandService;

    @Autowired
    private IDtrdEntRdDeviceService deviceService;

    private static final int BIOLAND_PORT = 8300;

    @Override
    public String onDataUpload(String data) {
//        log.info("DtrdEntRdBiolandPushContentServiceImpl.onDataUpload.[data] " + data);
        if (HdwDataCheckUtils.checkReceivedData(data)) {
            SrcDataValue srcDatavalue = new SrcDataValue(data);
            // 保存推送记录
            savePushContent(srcDatavalue.getSerialNumber(), data, srcDatavalue.getDeviceType());
            // 按类型存储为血糖或者血压记录
            saveRecord(srcDatavalue);
            return joinResponseData();
        } else {
            log.info("DtrdEntRdBiolandPushContentServiceImpl.onDataUpload.[data] 数据校验失败");
            return "数据校验失败";
        }
    }

    private String joinResponseData() {
        return "+IP" + getServerIp() + getServerDate() + "OK";
    }

    /**
     * 获取服务器时间
     *
     * @return
     */
    private String getServerDate() {
        StringBuilder datasb = new StringBuilder();
        int sum = 0;
        Calendar cal = Calendar.getInstance();
        Integer year = Integer.valueOf(cal.get(1) % 100);
        datasb.append(StringUtils.leftPad(Integer.toHexString(year.intValue()),
                2, "0"));
        sum ^= year.intValue();

        Integer month = Integer.valueOf(cal.get(2) + 1);
        datasb.append(StringUtils.leftPad(
                Integer.toHexString(month.intValue()), 2, "0"));
        sum ^= month.intValue();

        Integer day = Integer.valueOf(cal.get(5));
        datasb.append(StringUtils.leftPad(Integer.toHexString(day.intValue()),
                2, "0"));
        sum ^= day.intValue();

        Integer hour = Integer.valueOf(cal.get(11));
        datasb.append(StringUtils.leftPad(Integer.toHexString(hour.intValue()),
                2, "0"));
        sum ^= hour.intValue();

        Integer minute = Integer.valueOf(cal.get(12));
        datasb.append(StringUtils.leftPad(
                Integer.toHexString(minute.intValue()), 2, "0"));
        sum ^= minute.intValue();

        datasb.append(StringUtils.leftPad(Integer.toHexString(sum), 2, "0"));

        return datasb.toString().toUpperCase();
    }

    private String getServerIp() {
        String currServerIp = IpUtils.getLocalIp();

        String[] ips = currServerIp.split("\\.");

        if ((null == ips) || (0 >= ips.length)) {
            return "";
        }
        String ports = StringUtils.leftPad(Integer.toHexString(BIOLAND_PORT), 4, "0");
        StringBuilder ipsb = new StringBuilder();
        int sum = 0;
        for (int i = 0; i < ips.length; i++) {
            ipsb.append(StringUtils.leftPad(
                    Integer.toHexString(Integer.valueOf(ips[i]).intValue()), 2,
                    "0"));
            sum ^= Integer.valueOf(ips[i]).intValue();
        }
        sum ^= Integer.valueOf(ports.substring(2, 4), 16).intValue();
        ipsb.append(ports, 2, 4);
        sum ^= Integer.valueOf(ports.substring(0, 2), 16).intValue();
        ipsb.append(ports, 0, 2);
        ipsb.append(Integer.toHexString(sum));
        return ipsb.toString().toUpperCase();
    }

    private void saveRecord(SrcDataValue srcDatavalue) {
//        DtrdEntRdBioland bioland = queryRecordByDeviceSnAndDeviceType(srcDatavalue.getSerialNumber(), srcDatavalue.getDeviceType());
        DtrdEntRdDevice bioland = deviceService.selectOntByDeviceSnAndDeviceType(srcDatavalue.getSerialNumber(), DeviceBrand.BIOLAND.getBrand(), DeviceCategory.BLOODSUGAR.getCategory());
        if (bioland != null) {
            Integer type= Integer.valueOf(srcDatavalue.getDeviceType());
            // 仅针对当前绑定状态的设备推送做数据解析存储
            if (DeviceConstant.DeviceCategory.isSugar(type)) {
                sugarRecordService.saveBiolandRecord(srcDatavalue, bioland.getUserId());
            } else if (DeviceConstant.DeviceCategory.isBloodPressure(type)) {
                bloodPressureRecordService.saveBiolandRecord(srcDatavalue, bioland.getUserId());
            }
        }
    }

    @Deprecated
    private DtrdEntRdBioland queryRecordByDeviceSnAndDeviceType(String serialNumber, String deviceType) {
        return biolandService.selectOntByDeviceSnAndDeviceType(serialNumber, deviceType);
    }

    private void savePushContent(String serialNumber, String data, String deviceType) {
        DtrdEntRdBiolandPushContent entity = new DtrdEntRdBiolandPushContent().init();
        entity.setPushContent(data);
        entity.setDeviceSn(serialNumber);
        entity.setDeviceCategory(Integer.valueOf(deviceType));
        baseMapper.insert(entity);
    }

}
